var duel = duel || new Duel();

(function(duel){

  sign_wall_mode = (function(){
    function onLoad(){
      //Bind sign in
      $('#sign-in-button').click(function(){
        var errorSpot = 'sign-in';
        var $that = $(this);
        var email = $('#sign-in-email').val();
        var password = $('#sign-in-password').val();
        if(email.length == 0) { show_message(errorSpot,'Email is required'); return; }
        if(password.length == 0) { show_message(errorSpot,'Password is required'); return; }
        glass.think($that);
        duel.sign_in(email,password,function(success,why){
          glass.unthink($that);
          if(!success) {
            show_message(errorSpot,why);
          }
        });
      });

      $('#sign-up-button').click(function(){
        var $that = $(this);
        var errorSpot = 'sign-up';
        var name = $('#sign-up-name').val();
        var email = $('#sign-up-email').val();
        var password = $('#sign-up-password').val();
        if(name.length ==0) { show_message(errorSpot,'Name is required'); return;}
        if(email.length ==0) { show_message(errorSpot,'Email is required'); return;}
        if(password.length ==0) { show_message(errorSpot,'Password is required'); return;}
        glass.think($that);
        duel.create_user(name,email,password,function(success,why){
          glass.unthink($that);
          if(!success) {
            show_message(errorSpot,why);
          }
        });
      });

      glass.reselect();
    }

    function initialize(){
      
    }

    return {
      source: 'sign_wall',
      mode: 0,
      onLoad: onLoad,
      initialize: initialize
    }
  })(); 

  game_select_mode = (function(){
    function onLoad(){
      //Bind game selection
      $('#select-tab').on('click','button',function(){
        var $that = $(this);
        var game_id = $that.data('game-id');
        glass.think($that);
        duel.get_game(game_id,function(){
          glass.unthink($that);
        });
      });

      $('#start-game-button').click(function(){
        var $that = $(this);
        var errorSpot = 'create-tab';
        var theirEmail = $('#start-game-email').val();
        if(theirEmail == undefined || theirEmail.length == 0) {
          show_message(errorSpot,"Opponent's email is required");
          return;
        }
        glass.think($that);
        duel.start_game(theirEmail,function(success,why){
          glass.unthink($that);
          if(!success){
            show_message(errorSpot,why);
          }
        });
      });

      $('#refresh').click(function(){
        var $that = $(this);
        glass.think($that);
        duel.get_games(function(){
          glass.unthink($that);
        });
      });

      duel.get_games(); //Trigger a game list update
      glass.reselect();
    }

    function render_select_games() {
      var ready; 
      var waiting;

      ready = _(duel.games()).filter(function(iter){
        return iter.i_can_go();
      });
      
      waiting = _(duel.games()).filter(function(iter){
        return !iter.i_can_go();
      });

      function render_game_list($to,games){
        var html = "";
        _(games).each(function(game){
          var rowHtml = "<tr><td><button data-game-id='" + game.id() + "' ";
          rowHtml += "data-game-opponent='" + game.opponent.Email + "'>";
          rowHtml += game.opponent.Name + " &#8211; Turn " + game.turns();
          rowHtml += "</button></td></tr>";
          html += rowHtml;
        });
        $to.html(html);
      }

      render_game_list($('#ready'),ready);
      render_game_list($('#waiting'),waiting);
    }

    function initialize(){
      $(document).bind('games', render_select_games);
    }
    return {
      source: 'game_select',
      mode: 1,
      onLoad: onLoad,
      initialize: initialize
    }
  })(); 

  play_mode = (function(){
    var guess_buffer = '';
    var template_history_row;

    function compile_templates(){
      var strTemplate = $('#history_row').html();
      template_history_row = _.template(strTemplate);
    }

    function onLoad(){
      guess_buffer = '';
      compile_templates();
      //Bind to the letters
      $('table','#selector').on("click","div",function() {
        var $this = $(this);
        var letter = $this.html();
        duel.active_game().toggle(letter);
      });
      //Bind word entry
      $('#enter').click(function(){
        var $that = $(this);
        var game = duel.active_game();
        var word = $('#word').val();
        glass.think($that);
        game.enter_word(word,function(success,why){
          glass.unthink($that);
          if(!success)
            console.log("Failed to enter word: " + why);
            show_message('word_entry',why);
        });
      });
      //Bind Typing handler
      $('body').unbind('keydown').bind('keydown', typing_handler);
      //Bind guess entry
      $('#guess').click(function(){ make_guess(); });
      //Game navigation
      $('#refresh').click(function(){
        var $that = $(this);
        glass.think($that);
        duel.active_game().do_update(function(){
          glass.unthink($that);
        });
      });

      $('#back').click(function(){
        var $that = $(this);
        glass.think($that);
        duel.unload_active(function(){
          glass.unthink($that);
        });
      });

      render_selectors();
      render_history();
      render_game_state();
    }

    function make_guess() {
      var errorSpot = 'play';
      var $that = $('#guess')
      var game = duel.active_game();
      if(!game.i_can_go()) {
        show_message(errorSpot,"It's not your turn");
      }
      if(guess_buffer.length < 4)
      {
        show_message(errorSpot,
          "You're new in town, ain'y 'ya. Ya gotta guess four letter words");
        return;
      }
      glass.think($that);
      duel.active_game().guess(guess_buffer,function(success,why) {
        glass.unthink($that);
        console.log(success + ":" + why);
        if(success){
          guess_buffer = "";
          render_game_state();
          render_history();
          render_guess();
        }
        else {
          show_message(errorSpot,why);
        }
      });
    }

    function render_selectors(){
      var $selector = $('table','#selector');
      $selector.html('');
      var charOrdinals = _.range(65,91);
      var html = '';
      var curChar = 0;

      var count = 0;
      html = _.reduce(charOrdinals,function(memo,val){
        var html = render_token(String.fromCharCode(val));
        count += 1;
        if(count%9 === 0) { //Add row endings on the I and R
          html += '</tr><tr>';
        }
        return memo + html;
      },'<tr>');
      html += '</tr>';
      $selector.html(html);
    }

    function render_game_state() {
      var game = duel.active_game();
      var havePickedWord = game.my_word() != undefined;
      $('#word_entry').toggleClass('hidden',havePickedWord)
      $('#play').toggleClass('hidden',!havePickedWord)
      //Update player names
      $('.name','#left').html(game.me.Name);
      $('.name','#right').html(game.opponent.Name);
      //Update win/lose pictures
      if(game.game_over()) {
        var banner = game.winner() == 'tie' ? 'tie' : game.winner() == 'me'?'winner':'loser';
        $('.'+banner).show();
      }
    }
    
    function render_history() {
      var game = duel.active_game();
      var left = game.my_guesses();
      var right = game.their_guesses();
      var html = "";
      var $history = $('#history');
      $history.html(""); //Clear the history
      var maxLength = _.max([left.length,right.length]);
      for(var i=0; i<maxLength; ++i) {
        var strLeft = left[i];
        var strRight = right[i];

        var context = {
          left: strLeft,
          right: strRight,
          row: i,
          mark_as: markingClass,
          left_stars: game.my_stars()[i],
          right_stars: game.their_stars()[i]
        };
        var rowHtml = template_history_row(context);
        html += rowHtml;
      };
      $history.html(html);

      //Render turns
      $('.indicator','#left').toggleClass('invisible',!game.i_can_go());
      $('.indicator','#right').toggleClass('invisible',!game.they_can_go());
    }

    function render_guess() {
      var character;
      var html = "";
      for(var i=0; i<4; ++i) {
        character = guess_buffer.length -1 < i ? '' : guess_buffer[i];
        html += render_token(character);
      }
      $('table tr','#pad').html(html);
    }

    function render_token(letter) {
        var letter_html = '<td><div class="'
        letter_html += markingClass(letter);
        letter_html += '">'
        letter_html += letter;
        letter_html += '</div></td>';
        return letter_html;
    }

    function markingClass(letter) {
      if(letter=='') return 'token_ghost';
      var game = duel.active_game();
      if(game.is_marked(letter)) return 'token_red';
      if(game.is_grayed(letter)) return 'token_gray';
      return 'token_yellow';
    }

    // Prevent the backspace key from navigating back.
    function typing_handler(event) {
      if(event.target.tagName === "INPUT") return true;
      if(_getMode() != 2) return true;
      if(event.keyCode == 8)
      { 
        event.preventDefault();
        if(guess_buffer.length === 1) {
          guess_buffer = "";
        }
        else {
          guess_buffer = guess_buffer.substring(0,guess_buffer.length-1);
        }
        render_guess();
        return false;
      }
      else if(event.keyCode == 13) {
        make_guess();
        return false;
      }
      var character = String.fromCharCode(event.keyCode).toUpperCase();
      if(!/[A-Z]/.exec(character))
      {
        return true;
      }
      if(guess_buffer.length < 4) {
        guess_buffer += character;
        render_guess();
      }
    }

    function initialize(){
      //The main render for game changes
      $(document).bind('active_game', function() {
        //Setup the guesses
        render_selectors();
        render_history();
        render_game_state();
      });
      //Update marks
      $(document).bind('marks',function() {
        render_selectors();
        render_history();
      });
    }
    return {
      source: 'play',
      mode: 2,
      onLoad: onLoad,
      initialize: initialize
    }
  })(); 

  function show_message(parent,message) {
    var $messages = $('.messages','#'+parent);
    $messages.text(message);
    $messages.slideToggle('slow',function(){
      //Messages show for only a short while.
      setTimeout(function(){unshow_message($messages);},3000);
    });
  }

  function unshow_message($messages) {
    $messages.slideToggle('slow');
  }

  $(document).bind('enter_game',function() {
    change_modes();
  });


  $(document).bind('sign_in', function() {
    change_modes();
  });

  var modes = [sign_wall_mode, game_select_mode, play_mode];

  function change_modes() {
    var cur_mode = _getMode();
    console.log("Change modes to: " + cur_mode);
    var mode = modes[cur_mode];

    //Load the HTML for the new mode
    $('#holder').load(mode.source + '.html',function(){
      mode.onLoad();
    });

    //Toggle the sign out
    if(cur_mode === 1 || cur_mode === 2) {
      $('#welcome-name').text('Welcome ' + duel.user());
    }
    $('#welcome').toggleClass('invisible',cur_mode===0)
  }

  function _getMode() {
    if(!duel.is_signed_in()) return 0;
    if(duel.active_game() == undefined) return 1;
    return 2;
  }

  //Initialize all of the modes
  $(document).ready(function(){
    _(modes).each(function(mode){
      mode.initialize();
    });
    //Select the starting mode
    change_modes();
  });
})(duel);

